package org.bikelab.se3.rdf.reader;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.hadoop.conf.Configuration;
import org.bikelab.se3.index.Se3IndexWriter;
import org.semanticweb.yars.nx.Node;
import org.semanticweb.yars.nx.parser.NxParser;

public class RdfReaderFactory {
	private static final String patternStr = "_:(\\w+)";
	private static final String replaceStr = "<http://blanknode.com/$1>";
	private static final Pattern pattern = Pattern.compile(patternStr);
	
	public static Iterator<Node[]> createNxReaderForString(String nxLine) throws IOException {
		return new NxParser(new ByteArrayInputStream(nxLine.getBytes()), false);
	}
	
	public static Iterator<Node[]> createTrigReaderForStream(InputStream in) throws IOException {
		return new TrigParser(in);
	}

	public static Iterator<Node[]> createN3ReaderForString(String line) throws IOException {
Iterator<Node[]> parser = null;
				line = line.trim();
				if(line.isEmpty()) {
				} if(line.endsWith("{")) {
				} else if(line.startsWith("}")) {
				} else {
		Matcher matcher = pattern.matcher(line);
		line = matcher.replaceAll(replaceStr);
		parser = new N3Parser(new ByteArrayInputStream(line.getBytes()));
		}
		return parser;
	}
	
	public static Node[] parseNqLine(String nqLine) throws IOException, WrongNumberOfSegmentsException, NoLineToParseException {
		Iterator<Node[]> nxp = createNxReaderForString(nqLine);

		Node[] n = null;
		if(nxp.hasNext()) {
			n = nxp.next();
			if(n.length != 4) {
				throw new WrongNumberOfSegmentsException();
			}
		} else {
			throw new NoLineToParseException();
		}
		return n;
	}
	
	public static Node[] parseN3Line(String n3Line) throws IOException, WrongNumberOfSegmentsException, NoLineToParseException {
		Iterator<Node[]> nxp = createNxReaderForString(n3Line);

		Node[] n = null;
		if(nxp.hasNext()) {
			n = nxp.next();
			if(n.length != 3) {
				throw new WrongNumberOfSegmentsException();
			}
		} else {
			throw new NoLineToParseException();
		}
		return n;
	}

//	public static RdfReader getQuadReader(String string) throws QuadReaderException {
//		// TODO Auto-generated method stub
//		return null;
//	}

	public static RdfReader getRdfReader(Configuration conf) {
		final String[] classes = conf.getStrings("rdf.reader.class");
		if(classes == null) {
			throw new RuntimeException("No IndexWriter classes registered.");
		}
		final RdfReader[] readers = new RdfReader[classes.length];
		for (int i = 0; i < classes.length; i++) {
			final String clazz = classes[i];
			try {
				final Class<RdfReader> implClass = (Class<RdfReader>) Class
						.forName(clazz);
				readers[i] = implClass.newInstance();
			} catch (final Exception e) {
				throw new RuntimeException("Couldn't create " + clazz, e);
			}
		}
		return readers[0];
	}

	public static void addClassToConf(Configuration conf,
			Class<? extends RdfReader> clazz) {
		final String newClass = clazz.getName();
		addClassToConf(conf, newClass);
	}
	
	public static void addClassToConf(Configuration conf,
			String newClass) {
		conf.set("rdf.reader.class", newClass);
//
//		if (classes == null) {
//			conf.set("indexer.writer.classes", newClass);
//		} else {
//			conf.set("indexer.writer.classes", classes + "," + newClass);
//		}
	}
}
